#include "connectionwindow.h"
#include "connectionmanager.h"
#include "connectiondialog.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QListWidget>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QMessageBox>
#include <QApplication>

ConnectionWindow::ConnectionWindow(ConnectionManager *manager, QWidget *parent)
    : QDialog(parent)
    , m_connectionManager(manager)
{
    setupUI();
    loadConnections();
    selectionChanged();
}

QString ConnectionWindow::getSelectedConnection() const
{
    return m_selectedConnection;
}

void ConnectionWindow::addConnection()
{
    ConnectionDialog dialog(this);
    if (dialog.exec() == QDialog::Accepted) {
        QString name = dialog.getConnectionName();
        if (m_connectionManager->connectionExists(name)) {
            QMessageBox::warning(this, tr("Connection Exists"), 
                                tr("A connection with this name already exists."));
            return;
        }
        
        ConnectionConfig config;
        config.name = name;
        config.driver = dialog.getDriver();
        config.host = dialog.getHost();
        config.database = dialog.getDatabase();
        config.username = dialog.getUsername();
        config.password = dialog.getPassword();
        config.port = dialog.getPort();
        
        if (m_connectionManager->saveConnection(name, config)) {
            updateConnectionList();
        } else {
            QMessageBox::warning(this, tr("Error"), 
                                tr("Failed to save connection."));
        }
    }
}

void ConnectionWindow::editConnection()
{
    if (m_selectedConnection.isEmpty()) {
        return;
    }
    
    ConnectionConfig config = m_connectionManager->getConnection(m_selectedConnection);
    if (config.name.isEmpty()) {
        return;
    }
    
    ConnectionDialog dialog(this);
    dialog.setEditMode(true);
    dialog.setConnectionName(config.name);
    dialog.setDriver(config.driver);
    dialog.setHost(config.host);
    dialog.setDatabase(config.database);
    dialog.setUsername(config.username);
    dialog.setPassword(config.password);
    dialog.setPort(config.port);
    
    if (dialog.exec() == QDialog::Accepted) {
        // Only allow editing of certain fields, not the name
        config.driver = dialog.getDriver();
        config.host = dialog.getHost();
        config.database = dialog.getDatabase();
        config.username = dialog.getUsername();
        config.password = dialog.getPassword();
        config.port = dialog.getPort();
        
        if (m_connectionManager->saveConnection(m_selectedConnection, config)) {
            updateConnectionList();
        } else {
            QMessageBox::warning(this, tr("Error"), 
                                tr("Failed to update connection."));
        }
    }
}

void ConnectionWindow::removeConnection()
{
    if (m_selectedConnection.isEmpty()) {
        return;
    }
    
    int result = QMessageBox::question(this, tr("Confirm Removal"), 
                                      tr("Are you sure you want to remove the connection '%1'?")
                                      .arg(m_selectedConnection));
    
    if (result == QMessageBox::Yes) {
        if (m_connectionManager->removeConnection(m_selectedConnection)) {
            updateConnectionList();
            m_selectedConnection.clear();
            selectionChanged();
        } else {
            QMessageBox::warning(this, tr("Error"), 
                                tr("Failed to remove connection."));
        }
    }
}

void ConnectionWindow::connectToSelected()
{
    if (!m_selectedConnection.isEmpty()) {
        accept();
    }
}

void ConnectionWindow::selectionChanged()
{
    QList<QListWidgetItem *> selected = m_connectionList->selectedItems();
    bool hasSelection = !selected.isEmpty();
    
    m_editButton->setEnabled(hasSelection);
    m_removeButton->setEnabled(hasSelection);
    m_connectButton->setEnabled(hasSelection);
    
    if (hasSelection) {
        m_selectedConnection = selected.first()->text();
    } else {
        m_selectedConnection.clear();
    }
}

void ConnectionWindow::doubleClicked(QListWidgetItem *item)
{
    if (item) {
        m_selectedConnection = item->text();
        accept();
    }
}

void ConnectionWindow::setupUI()
{
    setWindowTitle(tr("Connection Manager"));
    setModal(true);
    resize(400, 300);
    
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    
    m_connectionList = new QListWidget;
    m_connectionList->setSelectionMode(QAbstractItemView::SingleSelection);
    mainLayout->addWidget(m_connectionList);
    
    QHBoxLayout *buttonLayout = new QHBoxLayout;
    
    m_addButton = new QPushButton(tr("Add"));
    m_editButton = new QPushButton(tr("Edit"));
    m_removeButton = new QPushButton(tr("Remove"));
    m_connectButton = new QPushButton(tr("Connect"));
    m_connectButton->setDefault(true);
    
    buttonLayout->addWidget(m_addButton);
    buttonLayout->addWidget(m_editButton);
    buttonLayout->addWidget(m_removeButton);
    buttonLayout->addStretch();
    buttonLayout->addWidget(m_connectButton);
    
    mainLayout->addLayout(buttonLayout);
    
    m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
    mainLayout->addWidget(m_buttonBox);
    
    connect(m_addButton, &QPushButton::clicked, this, &ConnectionWindow::addConnection);
    connect(m_editButton, &QPushButton::clicked, this, &ConnectionWindow::editConnection);
    connect(m_removeButton, &QPushButton::clicked, this, &ConnectionWindow::removeConnection);
    connect(m_connectButton, &QPushButton::clicked, this, &ConnectionWindow::connectToSelected);
    connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
    connect(m_connectionList, &QListWidget::itemSelectionChanged, this, &ConnectionWindow::selectionChanged);
    connect(m_connectionList, &QListWidget::itemDoubleClicked, this, &ConnectionWindow::doubleClicked);
}

void ConnectionWindow::loadConnections()
{
    updateConnectionList();
}

void ConnectionWindow::updateConnectionList()
{
    m_connectionList->clear();
    QStringList names = m_connectionManager->getConnectionNames();
    m_connectionList->addItems(names);
}